package com.hdy.common.network;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;
import android.util.Log;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

public class NetworkUtils {

    public static final int NETWORK_UNKNOWN = 0;
    public static final int NETWORK_WIFI = 1;
    public static final int NETWORK_MOBILE_2G = 2;
    public static final int NETWORK_MOBILE_3G = 3;
    public static final int NETWORK_MOBILE_4G = 4;

    public static final int TYPE_NO_NETWORK = 0;
    public static final int TYPE_WIFI = 1;
    public static final int TYPE_MOBILE = 2;
    public static final int TYPE_BLUETOOTH = 7;

    private static final int NETWORK_TYPE_GSM = 16;
    private static final int NETWORK_TYPE_TD_SCDMA = 17;
    private static final int NETWORK_TYPE_IWLAN = 18;
    private static final int NETWORK_TYPE_LTE_CA = 19;

    private final static String TAG = "NetworkUtils";

    public static boolean isAvailable(Context context) {
        NetworkInfo activeNetInfo = getNetWorkInfo(context);
        return activeNetInfo != null && activeNetInfo.isAvailable();
    }

    public static boolean isWifiAvailable(Context context) {
        return isAvailableByType(context, ConnectivityManager.TYPE_WIFI);
    }

    public static boolean isMobileAvailable(Context context) {
        return isAvailableByType(context, ConnectivityManager.TYPE_MOBILE);
    }

    public static boolean isBlueToothAvailable(Context context) {
        return isAvailableByType(context, ConnectivityManager.TYPE_BLUETOOTH);
    }

    private static boolean isAvailableByType(Context context, int type) {
        NetworkInfo info = getNetWorkInfo(context);
        if (null == info) {
            return false;
        }

        if (info.getType() == type) {
            return true;
        }
        return false;
    }

    private static NetworkInfo getNetWorkInfo(Context context) {
        try {
            ConnectivityManager connectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            return connectivityManager.getActiveNetworkInfo();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static int getNetType(Context context) {
        if (NetworkUtils.isWifiAvailable(context)) {
            return NETWORK_WIFI;
        }
        return NetworkUtils.getMobileNetworkType(context);
    }

    public static int getNetworkState(Context context) {
        int netWorkState = NetworkConstant.NO_NETWORK;
        NetworkInfo networkINfo = getNetWorkInfo(context);
        if (networkINfo == null || !networkINfo.isAvailable()) {
            Log.e(TAG, "networkINfo is null ");
            netWorkState = NetworkConstant.NO_NETWORK;
        } else {
            if (networkINfo.getType() == ConnectivityManager.TYPE_WIFI) {
                netWorkState = NetworkConstant.WLAN;
            }
            if (networkINfo.getType() == ConnectivityManager.TYPE_BLUETOOTH) {
                netWorkState = NetworkConstant.BLUETOOTH_NETWORK;
            }
            if (networkINfo.getType() == ConnectivityManager.TYPE_MOBILE
                    /*
                    || networkINfo.getType() == ConnectivityManager.TYPE_MOBILE_FOTA
                    || networkINfo.getType() == ConnectivityManager.TYPE_MOBILE_IMS
                    || networkINfo.getType() == ConnectivityManager.TYPE_MOBILE_CBS
                    */
                    || networkINfo.getType() == ConnectivityManager.TYPE_MOBILE_HIPRI
                    || networkINfo.getType() == ConnectivityManager.TYPE_MOBILE_DUN
                    || networkINfo.getType() == ConnectivityManager.TYPE_MOBILE_MMS
                    || networkINfo.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) {
                netWorkState = NetworkConstant.MOBILE_NETWORK;
            }
        }
        Log.e(TAG, "netWorkState = " + netWorkState);
        return netWorkState;
    }

    public static int getMobileNetworkType(Context context) {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        int type = tm.getNetworkType();
        switch (type) {
            case TelephonyManager.NETWORK_TYPE_GPRS:
            case TelephonyManager.NETWORK_TYPE_EDGE:
            case TelephonyManager.NETWORK_TYPE_CDMA:
            case TelephonyManager.NETWORK_TYPE_1xRTT:
            case TelephonyManager.NETWORK_TYPE_IDEN:
                return NETWORK_MOBILE_2G;
            case TelephonyManager.NETWORK_TYPE_UMTS:
            case TelephonyManager.NETWORK_TYPE_EVDO_0:
            case TelephonyManager.NETWORK_TYPE_EVDO_A:
            case TelephonyManager.NETWORK_TYPE_HSDPA:
            case TelephonyManager.NETWORK_TYPE_HSUPA:
            case TelephonyManager.NETWORK_TYPE_HSPA:
            case TelephonyManager.NETWORK_TYPE_EVDO_B:
            case TelephonyManager.NETWORK_TYPE_EHRPD:
            case TelephonyManager.NETWORK_TYPE_HSPAP:
                return NETWORK_MOBILE_3G;
            case TelephonyManager.NETWORK_TYPE_LTE:
            case NETWORK_TYPE_GSM:
            case NETWORK_TYPE_TD_SCDMA:
            case NETWORK_TYPE_IWLAN:
            case NETWORK_TYPE_LTE_CA:
                return NETWORK_MOBILE_4G;
            default:
                return NETWORK_UNKNOWN;
        }
    }

    public static String getNetworkType(Context context) {
        int state = NetworkUtils.getNetworkState(context);
        String netType = "";
        if (state == NetworkConstant.WLAN) {
            netType = "wifi";
        } else if (state == NetworkConstant.MOBILE_NETWORK) {
            int type = NetworkUtils.getMobileNetworkType(context);
            switch (type) {
                case NetworkUtils.NETWORK_MOBILE_2G:
                    netType = "2G";
                    break;
                case NetworkUtils.NETWORK_MOBILE_3G:
                    netType = "3G";
                    break;
                case NetworkUtils.NETWORK_MOBILE_4G:
                    netType = "4G";
                    break;
                default:
                    netType = "unknown";
                    break;
            }
        }
        return netType;
    }

    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager == null) {
            return false;
        } else {
            NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo();
            if (networkInfo != null && networkInfo.length > 0) {
                for (NetworkInfo aNetworkInfo : networkInfo) {
                    if (aNetworkInfo.getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public static String getNetWorkLabel(Context context) {
        if (isWifiAvailable(context)) {
            return "wifi";
        }

        switch (getMobileNetworkType(context)) {
            case NETWORK_MOBILE_2G:
                return "2g";
            case NETWORK_MOBILE_3G:
                return "3g";
            case NETWORK_MOBILE_4G:
                return "4g";
            default:
                return "";
        }
    }

    public static String getIPv4(Context context){
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
                {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && (inetAddress instanceof Inet4Address))
                    {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        }
        catch (SocketException ex){
            ex.printStackTrace();
        }
        return "";
    }

    public static String[] getWifiApAndRssi(Context context) {
        WifiManager wifi_service = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifi_service.getConnectionInfo();
        String[] result = new String[2];
        result[0] = wifiInfo.getSSID();
        result[1] = String.valueOf(wifiInfo.getRssi());
        return result;
    }
}